<script setup lang='ts'>
import {
  Search,
  Refresh,
  Plus,
  EditPen,
  DeleteFilled,
  Upload,
  Download,
  Menu,
  DArrowRight,
  Key,
  CircleCheck,
  UploadFilled,
} from "@element-plus/icons-vue";
import { onMounted, ref, reactive, watch } from "vue";
import { dateFormat } from "@/utils/time";
import { useUserStore } from "@/stores/modules/users";
import { useDeptStore } from "@/stores/modules/dept";
import { filterTree } from "@/utils/recuTree";

import type { FormInstance } from "element-plus";
import { ElMessage, ElMessageBox } from "element-plus";
import * as XLSX from "xlsx";
import { ElTree } from "element-plus";
const ruleFormRef = ref<FormInstance>();

const usersStore = useUserStore();
const deptStore = useDeptStore();

// 初始化列表
const deptList = ref([]);
onMounted(async () => {
  await usersStore.getList();
  await deptStore.getList();
  deptList.value = JSON.parse(JSON.stringify(filterTree(deptStore.list, 0)));
  // console.log(deptList.value);
});

// 分页
const small = ref(false);
const disabled = ref(false);

// 新增对话框
const dialogVisible = ref(false);
const addList = () => {
  dialogVisible.value = !dialogVisible.value;
};

////表格数据
let ruleForm = reactive({
  userName: "",
  nickName: "",
  gender: "",
  mobile: "",
  email: "",
  password: "",
  status: 1,
  remarks: "",
  department: "",
});

// 表单校验
const rules = reactive({
  userName: [{ required: true, message: "用户昵称不能为空", trigger: "blur" }],
  nickName: [{ required: true, message: "用户名称不能为空", trigger: "blur" }],
  password: [{ required: true, message: "用户密码不能为空", trigger: "blur" }],
});

// 取消提交
const cancel = () => {
  dialogVisible.value = !dialogVisible.value;
  Object.assign(ruleForm, {
    //清空表单
    userName: "",
    nickName: "",
    gender: "",
    mobile: "",
    email: "",
    password: "",
    status: 1,
    remarks: "",
    department: "",
  });
};

// 提交表单
const submitForm = async (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  await formEl.validate(async (valid, fields) => {
    if (valid) {
      dialogVisible.value = !dialogVisible.value;
      await usersStore.postSaveApi(ruleForm);
      usersStore.getList();
    }
  });
};

//控制修改 删除 按钮状态
let doUpdate = reactive({});
let disabledBtn = ref([]);
let ids = ref([]);
const handleSelectionChange = (item: any) => {
  doUpdate = item[0];
  ids.value = [];
  disabledBtn.value = item;
  item.forEach((v: any, i: any) => {
    ids.value.push(v.id);
  });
};

// 删除
const deleteData = async (id: any) => {
  ElMessageBox.confirm(`是否确认删除用户id为${id}的数据项?`, "系统提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(async () => {
    await usersStore.getDelete({ id });
    usersStore.getList();
    ElMessage({
      type: "success",
      message: "删除用户成功",
    });
  });
};
const open = () => {
  ElMessageBox.confirm("是否确认删除用户编号为1的数据项?", "系统提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(async () => {
      await usersStore.getDelete({ id: ids.value.join(",") });
      usersStore.getList();
      ElMessage({
        type: "success",
        message: "删除用户成功",
      });
    })
    .catch(() => {});
};

// 修改
const updata = async (row: any) => {
  if (row) {
    Object.assign(ruleForm, row);
    await usersStore.postSaveApi(Object.assign(ruleForm, { id: row.id }));
  } else {
    Object.assign(ruleForm, doUpdate);
    await usersStore.postSaveApi(Object.assign(ruleForm, { id: doUpdate.id }));
  }
  dialogVisible.value = !dialogVisible.value;
};

//搜索
const search = () => {
  usersStore.getList();
};
//重置
const refresh = async () => {
  usersStore.query1 = "";
  usersStore.query2 = "";
  usersStore.query3 = "";
  usersStore.query4 = "";
  usersStore.query5 = "";
  usersStore.query6 = "";
  fliterDept.value = "";
  await usersStore.getList();
};
// 分页
const handleSizeChange = (val: number) => {
  usersStore.pageSize = val;
  usersStore.getList();
};
const handleCurrentChange = (val: number) => {
  usersStore.currentPage = val;
  usersStore.getList();
};
// 显示搜索
const isShowSearch = ref(true);
const isShow = () => {
  isShowSearch.value = !isShowSearch.value;
};
// 状态开关
const statusSwitch = (row: any) => {
  let statu = ref();
  if (row.status) {
    statu.value = true;
  } else {
    statu.value = false;
  }
  console.log(statu.value);
  ElMessageBox.confirm(
    `确定要${statu.value ? "启用" : "停用"}嘛?`,
    "系统提示",
    {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning",
    }
  )
    .then(async () => {
      await usersStore.postSaveApi({ ...row, status: statu.value });
      usersStore.getList();
    })
    .catch(() => {
      usersStore.getList();
      // usersStore.postSaveApi({ row });
    });
};
// 重置密码
const passwordCkl = (row: any) => {
  console.log(row.password);

  ElMessageBox.prompt(`请重置${row.userName}的密码`, "提示 ", {
    confirmButtonText: "OK",
    cancelButtonText: "取消",
    inputPattern: /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,16}$/,
    inputErrorMessage: "只能包含字母和数字的 不低于6位",
  })
    .then(async ({ value }) => {
      await usersStore.postSaveApi({ ...row, password: value });
      usersStore.getList();
      ElMessage({
        type: "success",
        message: `密码已修改为:${value}`,
      });
    })
    .catch(() => {
      usersStore.getList();
    });
};
// 刷新
const loading = ref(false);
const refurbish = () => {
  loading.value = true;
  setTimeout(() => {
    loading.value = false;
  }, 1000);
};
// 显隐列
const dialogTableVisible = ref(false);
const valueTransfer = ref();
const showColumn = () => {
  dialogTableVisible.value = true;
};
let dataTransfer = reactive([
  {
    key: 1,
    label: "用户编号",
    show: true,
  },
  {
    key: 2,
    label: "用户名称",
    show: true,
  },
  {
    key: 3,
    label: "用户昵称",
    show: true,
  },
  {
    key: 4,
    label: "部门",
    show: true,
  },
  {
    key: 5,
    label: "手机号码",
    show: true,
  },
  {
    key: 6,
    label: "状态",
    show: true,
  },
  {
    key: 7,
    label: "创建时间",
    show: true,
  },
]);
const transferChange = (key: any, direction: any) => {
  if (direction == "right") {
    dataTransfer.filter((item, i) => {
      // includes查找数组或字符串字符串是否包含某项 返回值是布尔值
      if (key.includes(item.key)) {
        item.show = false;
      }
    });
  } else {
    dataTransfer.filter((item, i) => {
      if (!key.includes(item.key)) {
        item.show = true;
      }
    });
  }
};

// 导出
const ExportXlsx = () => {
  let head = {
    id: "id",
    userName: "用户名称",
    nickName: "用户昵称",
    gender: "性别",
    mobile: "手机号码",
    email: "邮箱",
    password: "密码",
    status: "状态",
    remarks: "备注",
    creatTime: "时间",
    department: "部门",
  };
  const list = usersStore.list.map((item) => {
    const obj = {};
    for (const k in item) {
      if (head[k]) {
        obj[head[k]] = item[k];
      }
    }
    return obj;
  });
  // 创建工作表
  const data = XLSX.utils.json_to_sheet(list);
  // 创建工作簿
  const wb = XLSX.utils.book_new();
  // 将工作表放入工作簿中
  XLSX.utils.book_append_sheet(wb, data, "客户信息");
  // 生成文件并下载
  XLSX.writeFile(wb, "客户管理表.xlsx");
};
// 导入
const xlsxVisible = ref();
let xlsxData = ref([]);
let head = {
  id: "id",
  用户名称: "userName",
  用户昵称: "nickName",
  性别: "gender",
  手机号码: "mobile",
  邮箱: "email",
  密码: "password",
  状态: "status",
  备注: "remarks",
  时间: "creatTime",
  部门: "department",
};
const ImportXlsx = (e: any) => {
  // xlsxVisible.value = false;
  // const file = e.target.files[0];
  const reader = new FileReader();
  reader.readAsArrayBuffer(e);
  reader.onload = (e: any) => {
    let data = e.target.result;
    const workbook = XLSX.read(data, {
      type: "binary",
      cellDates: true, //设为true，将天数的时间戳转为时间格式
    });
    const wsname = workbook.SheetNames[0];
    const outdata = XLSX.utils.sheet_to_json(workbook.Sheets[wsname]);
    xlsxData = deal(outdata, head);
  };
  function deal(data: any, key) {
    data.forEach((item: any) => {
      Object.keys(item).map((keys) => {
        let newKey = key[keys];
        if (newKey) {
          item[newKey] = item[keys];
          delete item[keys];
        }
      });
    });
    // data.forEach((item: any) => {
    //   item.date = moment(item.date).add(1, "d").format("YYYY-MM-DD");
    // });
    return data;
  }
};
const submitXlsx = () => {
  xlsxData.forEach(async (item) => {
    await usersStore.postSaveApi(item);
    await usersStore.getList();
    xlsxVisible.value = false;
  });
};

// 日期
const value1 = ref([]);
const DateChange = () => {
  usersStore.query4 = value1.value[0];
  usersStore.query5 = value1.value[1];
};

//清空表单
const reset = () => {
  Object.assign(ruleForm, {
    userName: "",
    nickName: "",
    gender: "",
    mobile: "",
    email: "",
    password: "",
    status: 1,
    remarks: "",
    department: "",
  });
};

const propsTree = reactive({
  label: "deptName",
  value: "deptName",
  children: "children",
});
const fliterDept = ref();
const treeRef = ref<InstanceType<typeof ElTree>>();
watch(fliterDept, (val) => {
  treeRef.value!.filter(val);
});

const filterNode = (value: string, data: any) => {
  if (!value) return true;
  return data.deptName.includes(value);
};
const filtertion = (data: any) => {
  // console.log(data);
  usersStore.query6 = data.deptName;
  usersStore.getList();
};
</script>

<template>
  <!-- 侧边导航栏 -->
  <el-row class="main">
    <el-col class="padd-10" :span="4">
      <el-input
        v-model="fliterDept"
        class="w-50 m-2"
        placeholder="请输入部门名称"
        :prefix-icon="Search" />
      <el-tree
        ref="treeRef"
        default-expand-all
        :data="deptList"
        :props="propsTree"
        check-strictly
        :filter-node-method="filterNode"
        @node-click="filtertion"
    /></el-col>
    <!-- 搜索 -->
    <el-col class="padd-20" :span="20">
      <el-form
        v-if="isShowSearch"
        :inline="true"
        class="form-1 demo-form-inline"
      >
        <el-form-item label="用户名称">
          <el-input v-model="usersStore.query1" placeholder="请输入用户名称" />
        </el-form-item>
        <el-form-item label="手机号码">
          <el-input v-model="usersStore.query2" placeholder="请输入手机号码" />
        </el-form-item>
        <el-form-item label="状态">
          <el-select v-model="usersStore.query3" placeholder="用户状态">
            <el-option label="停用" :value="0" />
            <el-option label="启用" :value="1" />
          </el-select>
        </el-form-item>
        <el-form-item label="创建时间">
          <div class="block">
            <el-date-picker
              v-model="value1"
              type="daterange"
              range-separator="-"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              value-format="YYYY-MM-DD"
              @change="DateChange"
            />
          </div>
        </el-form-item>
        <el-form-item label="">
          <el-button type="primary" @click="search" :icon="Search"
            >搜索</el-button
          >
          <el-button @click="refresh" :icon="Refresh">重置</el-button>
        </el-form-item>
      </el-form>
      <div class="icon">
        <!-- 按钮组 -->
        <div>
          <el-button type="primary" @click="addList" :icon="Plus" plain
            >新增</el-button
          >
          <el-button
            type="success"
            @click="updata(false)"
            :disabled="disabledBtn.length != 1"
            :icon="EditPen"
            plain
            >修改</el-button
          >
          <el-button
            type="danger"
            :disabled="disabledBtn.length == 0"
            :icon="DeleteFilled"
            @click="open"
            >删除</el-button
          >
          <el-button
            type="warning"
            @click="xlsxVisible = true"
            :icon="Upload"
            plain
            >导入</el-button
          >
          <el-button type="info" @click="ExportXlsx" :icon="Download" plain
            >导出</el-button
          >
        </div>
        <div class="btnGroup">
          <el-tooltip content="隐藏搜索" placement="top">
            <el-button @click="isShow" :icon="Search" circle />
          </el-tooltip>
          <el-tooltip content="刷新" placement="top">
            <el-button @click="refurbish" :icon="Refresh" circle />
          </el-tooltip>
          <el-tooltip content="显隐列" placement="top">
            <el-button @click="showColumn" :icon="Menu" circle />
          </el-tooltip>
        </div>
      </div>
      <!-- 表格 -->
      <el-table
        v-loading="loading"
        :data="usersStore.list"
        :header-cell-style="{ background: '#f8f8f9', color: '#606266' }"
        style="width: 100%"
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" />
        <el-table-column
          prop="date"
          label="用户编号"
          width="100"
          v-if="dataTransfer[0].show"
        >
          <template #default="scope">
            <span>
              {{ scope.$index + 1 }}
            </span>
          </template>
        </el-table-column>
        <el-table-column
          v-if="dataTransfer[1].show"
          prop="userName"
          label="用户名称"
          width="100"
        />
        <el-table-column
          v-if="dataTransfer[2].show"
          prop="nickName"
          label="用户昵称"
          width="100"
        />
        <el-table-column
          v-if="dataTransfer[3].show"
          prop="department"
          label="部门"
          width="100"
        />
        <el-table-column
          v-if="dataTransfer[4].show"
          prop="mobile"
          label="手机号码"
          width="120"
        />
        <el-table-column
          v-if="dataTransfer[5].show"
          prop="status"
          label="状态"
          width="100"
        >
          <template #default="scope">
            <el-switch
              @click="statusSwitch(scope.row)"
              v-model="scope.row.status"
              :active-value="1"
              :inactive-value="0"
            />
          </template>
        </el-table-column>
        <el-table-column
          v-if="dataTransfer[6].show"
          prop="creatTime"
          label="创建时间"
        >
          <template #default="scope">
            {{ dateFormat(scope.row.creatTime) }}
          </template>
        </el-table-column>
        <el-table-column prop="name" label="操作">
          <template #default="scope">
            <div>
              <el-link @click="updata(scope.row)" type="primary" :icon="EditPen"
                >Edit</el-link
              >
              <el-link
                @click="deleteData(scope.row.id)"
                type="primary"
                :icon="DeleteFilled"
                >删除</el-link
              >
              <el-dropdown style="margin-top: 5px">
                <span class="el-dropdown-link">
                  <el-link type="primary" :icon="DArrowRight">更多</el-link>
                </span>
                <template #dropdown>
                  <el-dropdown-menu>
                    <el-dropdown-item
                      @click="passwordCkl(scope.row)"
                      :icon="Key"
                      >重置密码</el-dropdown-item
                    >
                    <el-dropdown-item :icon="CircleCheck"
                      >分配角色</el-dropdown-item
                    >
                  </el-dropdown-menu>
                </template>
              </el-dropdown>
            </div>
          </template>
        </el-table-column>
      </el-table>
      <!-- 分页 -->
      <el-pagination
        :current-page="usersStore.currentPage"
        :page-size="usersStore.pageSize"
        :page-sizes="[1, 2, 3, 4]"
        :small="small"
        :disabled="disabled"
        background
        layout="total, sizes, prev, pager, next, jumper"
        :total="usersStore.total"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </el-col>
  </el-row>
  <!-- 新增&&修改 对话框 -->
  <el-dialog @close="reset" v-model="dialogVisible" title="新增" width="40%">
    <el-form
      ref="ruleFormRef"
      :inline="true"
      :model="ruleForm"
      :rules="rules"
      class="demo-form-inline"
    >
      <el-form-item label="用户昵称" prop="userName">
        <el-input v-model="ruleForm.userName" placeholder="请输入用户昵称" />
      </el-form-item>
      <el-form-item label="归属部门">
        <el-tree-select
          v-model="ruleForm.department"
          :data="deptList"
          :props="propsTree"
          :check-strictly="true"
          :render-after-expand="false"
        />
      </el-form-item>
      <el-form-item label="手机号码">
        <el-input v-model="ruleForm.mobile" placeholder="请输入手机号码" />
      </el-form-item>
      <el-form-item label="邮箱">
        <el-input v-model="ruleForm.email" placeholder="请输入用户邮箱" />
      </el-form-item>
      <el-form-item label="用户名称" prop="nickName">
        <el-input v-model="ruleForm.nickName" placeholder="请输入用户名称" />
      </el-form-item>
      <el-form-item label="用户密码" prop="password">
        <el-input
          type="password"
          v-model="ruleForm.password"
          placeholder="请输入用户密码"
        />
      </el-form-item>
      <el-form-item label="用户性别">
        <el-select v-model="ruleForm.gender" placeholder="请选择性别">
          <el-option label="男" value="shanghai" />
          <el-option label="女" value="beijing" />
          <el-option label="未知" value="beijing" />
        </el-select>
      </el-form-item>
      <el-form-item label="状态">
        <el-radio-group v-model="ruleForm.status">
          <el-radio :label="1">启用</el-radio>
          <el-radio :label="0">停用</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="岗位">
        <el-select placeholder="请选择岗位">
          <el-option label="董事长" value="shanghai" />
          <el-option label="项目经理" value="beijing" />
          <el-option label="人力资源" value="beijing" />
          <el-option label="普通员工" value="beijing" />
        </el-select>
      </el-form-item>
      <el-form-item label="角色">
        <el-select placeholder="请选择角色">
          <el-option label="普通角色" value="shanghai" />
        </el-select>
      </el-form-item>
      <el-form-item label="备注">
        <el-input
          v-model="ruleForm.remarks"
          type="textarea"
          cols="70"
          rows="2"
        />
      </el-form-item>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="cancel">取消</el-button>
        <el-button type="primary" @click="submitForm(ruleFormRef)">
          确定
        </el-button>
      </span>
    </template>
    <!-- 显隐列 -->
  </el-dialog>
  <el-dialog v-model="dialogTableVisible" title="显示/隐藏">
    <el-transfer
      v-model="valueTransfer"
      :data="dataTransfer"
      @change="transferChange"
    />
  </el-dialog>
  <!-- 导入对话框 -->
  <el-dialog v-model="xlsxVisible" title="用户导入" width="30%">
    <el-upload
      class="upload-demo"
      drag
      action=""
      multiple
      :before-upload="ImportXlsx"
    >
      <el-icon class="el-icon--upload"><upload-filled /></el-icon>
      <div class="el-upload__text">将文件拖到此处 <em>将文件拖到此处</em></div>
      <template #tip>
        <div class="el-upload__tip">
          <el-checkbox size="large" />
          是否更新已经存在的用户数据
        </div>
        <div class="center">
          仅允许导入xls、xlsx格式文件。
          <a
            href="http://localhost:3001/upload/%E7%94%A8%E6%88%B7%E7%AE%A1%E7%90%86%E8%A1%A8.xlsx"
            >下载模板</a
          >
        </div>
      </template>
    </el-upload>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="xlsxVisible = false">取消</el-button>
        <el-button type="primary" @click="submitXlsx"> 提交 </el-button>
      </span>
    </template>
  </el-dialog>
</template>

<style scoped>
.center {
  text-align: center;
}
.el-upload__tip {
  text-align: center;
  vertical-align: 10px;
}
.btnGroup {
  margin-left: 600px;
}
.icon-mar20 {
  margin-right: 20px;
}
.el-tooltip {
  margin-left: 10px;
}
.el-pagination {
  margin-top: 10px;
  float: right;
}
.el-link {
  margin-right: 10px;
}
.el-table >>> .cell {
  text-align: center;
}
/* text-align: center; */
/* .el-table >>> .el-table-column {
  font-weight: 700;
} */
.el-table {
  margin-top: 10px;
}
.icon {
  display: flex;
  /* justify-content: space-between; */
}
.el-tree {
  margin-top: 15px;
}
.padd-10 {
  padding: 0 10px;
}
.padd-20 {
  padding: 0 20px;
}
.main >>> .el-form-item__label {
  font-weight: 800;
}
.block >>> .el-date-editor {
  width: 240px;
}
.form-1 >>> .el-input {
  width: 240px;
}
</style>